import win32gui , win32con
import win32api
from typing import Dict , List
from utils import log_message
# 窗口信息类
class WindowInfo:
    def __init__(self, hwnd: int):
        # 获取窗口句柄
        self.hwnd : int = hwnd
        # 获取窗口名称
        self.title : str = win32gui.GetWindowText(hwnd)
        # 获取窗口位置
        self.position : tuple = win32gui.GetWindowRect(hwnd)
        # 获取窗口大小
        self.size : tuple = (self.position[2] - self.position[0], self.position[3] - self.position[1])
        # 获取窗口是否可见  
        self.is_visible : bool = win32gui.IsWindowVisible(hwnd)
        # 获取窗口是否启用
        self.is_enabled : bool = win32gui.IsWindowEnabled(hwnd)
        # 获取窗口是否被最小化
        self.is_minimized : bool = win32gui.IsIconic(hwnd)
        # 是否为主窗口
        self.is_main : bool = False
        

    # 转换为字典
    def to_dict(self) -> dict:
        return {
            "hwnd": self.hwnd,
            "title": self.title,
            "position": self.position,
            "size": self.size,
            "is_visible": self.is_visible,
            "is_enabled": self.is_enabled,
            "is_minimized": self.is_minimized,
            "is_main": self.is_main,
        }

# 窗口工具类
class WindowTools:
    
    # 游戏窗口类名
    GAME_CLASS_NAME = "MainWnd class of ArkEngine"
    
    # 窗口信息
    WINDOW_INFO  = {}
    
    # 只保留窗口大小配置
    WINDOW_SIZE = (1200, 700)
    
    # 初始化
    def __init__(self):
        # 窗口句柄列表
        self.hwnd_list = []
        # 窗口列表
        self.window_list = []
        
        pass
    
    def get_and_arrange_windows(self) -> List[WindowInfo]:
        """获取所有游戏窗口并自动排列"""
        self.window_list = []
        
        def calculate_grid_layout(total_windows: int) -> tuple:
            """计算最佳网格布局（行数和列数）"""
            screen_width = win32api.GetSystemMetrics(0)
            screen_height = win32api.GetSystemMetrics(1)
            
            # 计算屏幕可容纳的最大行列数
            max_cols = max(1, screen_width // self.WINDOW_SIZE[0])
            max_rows = max(1, screen_height // self.WINDOW_SIZE[1])
            
            # 尝试找到最合适的行列数
            cols = min(max_cols, total_windows)
            rows = (total_windows + cols - 1) // cols
            
            # 如果高度超出屏幕，重新调整
            if rows > max_rows:
                rows = max_rows
                cols = min(max_cols, (total_windows + rows - 1) // rows)
            
            return rows, cols
        
        def calculate_window_position(total_windows: int, index: int) -> tuple:
            """计算每个窗口的位置，从左上角(0,0)开始"""
            rows, cols = calculate_grid_layout(total_windows)
            
            # 计算当前窗口的行列位置
            row = index // cols
            col = index % cols
            
            # 直接计算坐标，从(0,0)开始
            x = col * self.WINDOW_SIZE[0]
            y = row * self.WINDOW_SIZE[1]
            
            return (x, y)
        
        def collect_windows(hwnd, _):
            try:
                if win32gui.GetClassName(hwnd) == self.GAME_CLASS_NAME:
                    window_info = WindowInfo(hwnd)
                    if window_info.is_visible:
                        self.window_list.append(window_info)
            except Exception as e:
                log_message(f"收集窗口失败: {e}", "error")
        
        # 收集窗口
        win32gui.EnumWindows(collect_windows, None)
        
        # 根据窗口数量自动排列
        window_count = len(self.window_list)
        for i, window in enumerate(self.window_list):
            try:
                x, y = calculate_window_position(window_count, i)
                win32gui.SetWindowPos(
                    window.hwnd, 
                    win32con.HWND_TOP,
                    x, y,
                    self.WINDOW_SIZE[0], self.WINDOW_SIZE[1],
                    win32con.SWP_SHOWWINDOW
                )
            except Exception as e:
                log_message(f"调整窗口位置失败: {e}", "error")
        
        return self.window_list

    def get_window(self) -> List[WindowInfo]:
        """获取所有游戏窗口（不改变窗口位置）"""
        self.window_list = []
        
        def collect_windows(hwnd, _):
            try:
                if win32gui.GetClassName(hwnd) == self.GAME_CLASS_NAME:
                    window_info = WindowInfo(hwnd)
                    if window_info.is_visible:
                        self.window_list.append(window_info)
            except Exception as e:
                log_message(f"收集窗口失败: {e}", "error")
        
        # 收集窗口
        win32gui.EnumWindows(collect_windows, None)
        return self.window_list

 
